//
//  GTFlutterMessageCenter.swift
//  lib_core
//
//  Created by Shper on 2023/9/7.
//
import Foundation

public class GTFlutterMessageCenter {
    
    static let shared: GTFlutterMessageCenter = GTFlutterMessageCenter()
    
    private init() {}
    
    private var _listenerDic: [String: [GTMessageCenterCallback?]] = [:]
    
    // 发送消息
    public static func sendMessage(_ message: GTFlutterMessageProtocol) {
        if (message.actionName.isEmpty) {
            debugPrint("GTFlutterMessageCenter - The action is invali.")
            return
        }
        guard let messageJsonData = try? JSONEncoder().encode(message) else {
            debugPrint("GTFlutterMessageCenter - The message is invali.")
            return
        }
        let messageJson = String(decoding: messageJsonData, as: UTF8.self)
        
        GTLibCoreFlutterPlugin.messageChannelList.forEach { messageChannelFlutterApi in
            messageChannelFlutterApi?.handleMessage(actionType: message.actionType,
                                                    actionName: message.actionName,
                                                    messageJson: messageJson,
                                                    completion: {_ in })
        }
    }
    
    // 发送消息
    public static func sendMessage(actionType: String, actionName: String, messageJson: String) {
        if (actionType.isEmpty || actionName.isEmpty) {
            debugPrint("GTFlutterMessageCenter - The action is invali.")
            return
        }
        
        GTLibCoreFlutterPlugin.messageChannelList.forEach { messageChannelFlutterApi in
            messageChannelFlutterApi?.handleMessage(actionType: actionType,
                                                    actionName: actionName,
                                                    messageJson: messageJson,
                                                    completion: {_ in })
        }
    }
    
    // 添加监听器
    public static func addListener(action: GTFlutterMessageProtocol, callback: GTMessageCenterCallback) {
        let actionKey = _generateActionKey(action.actionType, action.actionName)
        var callbacks = shared._listenerDic[actionKey] ?? []
        callbacks.removeAll { $0 == nil }
        callbacks.append(callback)
        shared._listenerDic[actionKey] = callbacks
    }
    
    // 添加监听器
    public static func addListener(actionType: String, actionName: String, callback: GTMessageCenterCallback) {
        let actionKey = _generateActionKey(actionType, actionName)
        var callbacks = shared._listenerDic[actionKey] ?? []
        callbacks.removeAll { $0 == nil }
        callbacks.append(callback)
        shared._listenerDic[actionKey] = callbacks
    }
    
    // 移除监听器
    public static func removeListener(actionType: String, actionName: String, callback: GTMessageCenterCallback? = nil) {
        let actionKey = _generateActionKey(actionType, actionName)
        var callbacks = shared._listenerDic[actionKey] ?? []
        callbacks.removeAll { $0 == nil }
        callbacks.removeAll { $0?.uuid == callback?.uuid }
    }
    
    // 移除监听器
    public static func removeListener(action: GTFlutterMessageProtocol, callback: GTMessageCenterCallback? = nil) {
        let actionKey = _generateActionKey(action.actionType, action.actionName)
        var callbacks = shared._listenerDic[actionKey] ?? []
        callbacks.removeAll { $0 == nil }
        callbacks.removeAll { $0?.uuid == callback?.uuid }
    }

    // 消息分发
    internal static func _dispatchMassage(actionType: String, actionName: String, messageJson: String) {
        let actionKey = _generateActionKey(actionType, actionName)
        var callbacks = shared._listenerDic[actionKey] ?? []
        callbacks.removeAll { $0 == nil }
        callbacks.forEach { callback in
            callback?.receiveMessage(actionType: actionType,
                                     actionName: actionName,messageJson: messageJson)
        }
    }
    
    // 根据 actionType 和 actionName 生成 actionKey
    internal static func _generateActionKey(_ actionType: String, _ actionName: String) -> String {
        return "\(actionType).\(actionName)"
    }

}

public protocol GTMessageCenterCallback {
    
    var uuid: String { get set }
    
    func receiveMessage(actionType: String, actionName: String, messageJson: String)
    
}
